package com.dao.impl;

import java.util.List;

import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.classic.Session;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.dao.UserDAO;
import com.model.Tag;
import com.model.User;
import com.util.Page;

@Repository
public class UserDAOImpl implements UserDAO {
	@Autowired
	private SessionFactory sessionFactory;

	public boolean addUser(User user) {
		try {
			sessionFactory.getCurrentSession().save(user);
			return true;
		} catch (Exception e) {
			e.printStackTrace();
			return false;
		}
	}

	@SuppressWarnings("unchecked")
	public List<User> findByNameOrEmail(String nameOrEmail) {

		Session s = sessionFactory.getCurrentSession();
		String hql = "from User as u where u.name=:name or u.email=:email";
		Query query = s.createQuery(hql);
		query.setString("name", nameOrEmail);
		query.setString("email", nameOrEmail);
		return query.list();

	}

	@SuppressWarnings("unchecked")
	public List<User> findByName(String name) {

		Session s = sessionFactory.getCurrentSession();
		String hql = "from User as u where u.name=:name";
		Query query = s.createQuery(hql);
		query.setString("name", name);
		return query.list();

	}

	@SuppressWarnings("unchecked")
	public List<User> findByEmail(String email) {

		Session s = sessionFactory.getCurrentSession();
		String hql = "from User as u where u.email=:email";
		Query query = s.createQuery(hql);
		query.setString("email", email);
		return query.list();

	}
	

	public User findByPriUrl(String uri) {
		// TODO Auto-generated method stub
		Session s = sessionFactory.getCurrentSession();
		String hql = "from User as u where u.privateUrl=:Url";
		Query query = s.createQuery(hql);
		query.setString("Url", uri);
		List ulist = query.list();
		if(ulist.size()>0){
			return (User) ulist.get(0);
		}else{
			return null;
		}
	}

	public User findById(int id) {
		User user = (User) sessionFactory.getCurrentSession().get(User.class,
				id);

		return user;
	}

	public void addUserTag(int tagId, int userId) {
		Session s = sessionFactory.getCurrentSession();
		String sql = "insert into user_tag(user_id,tag_id) values(:userId,:tagId)";
		Query query = s.createSQLQuery(sql);
		query.setInteger("userId", userId);
		query.setInteger("tagId", tagId);
		query.executeUpdate();
	}

	public void deleteUserTag(int tagId, int userId) {
		try {
			Session s = sessionFactory.getCurrentSession();
			String sql = "delete from user_tag where user_id=:userId and tag_id=:tagId";
			Query query = s.createSQLQuery(sql);
			query.setInteger("userId", userId);
			query.setInteger("tagId", tagId);
			query.executeUpdate();
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
	}

	public boolean isTagExist(int tagId, int userId) {
		Session s = sessionFactory.getCurrentSession();
		String sql = "select count(*) from user_tag where user_id=:userId and tag_id=:tagId";
		Query query = s.createSQLQuery(sql);
		query.setInteger("userId", userId);
		query.setInteger("tagId", tagId);

		int count = Integer.parseInt((query.uniqueResult().toString()));

		if (count > 0) {
			return true;
		} else {
			return false;
		}

	}

	public void addQuestionsNum(int id) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.questionsNum=u.questionsNum+1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
	}

	public void reduceQuestionsNum(int id) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.questionsNum=u.questionsNum-1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
	}

	public void addFavorNum(int id) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.favorNum=u.favorNum+1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
	}

	public void addAnswersNum(int id) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.answersNum=u.answersNum+1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
	}

	public void addArticleNum(int id) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.articleNum=u.articleNum+1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
	}

	public void addFollowNum(int id) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.followNum=u.followNum+1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
	}

	public void addFansNum(int id) {
		try {
			Session s = sessionFactory.getCurrentSession();
			String hql = "update User as u set u.fansNum=u.fansNum+1 where u.id=:id";
			Query q = s.createQuery(hql);
			q.setInteger("id", id);
			q.executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println(e.getMessage());
		}
	}

	public void reduceScore(int id, int score) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.score=u.score-" + score
				+ " where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
	}

	public void addScore(int id, int score) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.score=u.score+" + score
				+ " where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();
	}

	public boolean isNameExist(String name) {
		Session s = sessionFactory.getCurrentSession();
		String sql = "select count(*) from user where name=:name";
		Query query = s.createSQLQuery(sql);
		query.setString("name", name);

		int count = Integer.parseInt((query.uniqueResult().toString()));

		if (count > 0) {
			return true;
		} else {
			return false;
		}

	}

	public boolean isEmailExist(String email) {
		Session s = sessionFactory.getCurrentSession();
		String sql = "select count(*) from user where email=:email";
		Query query = s.createSQLQuery(sql);
		query.setString("email", email);

		int count = Integer.parseInt((query.uniqueResult().toString()));

		if (count > 0) {
			return true;
		} else {
			return false;
		}

	}

	
	
	public boolean isPrivateUrlExist(String privateUrl,int excludeId) {
		Session s = sessionFactory.getCurrentSession();
		String sql = "select count(*) from user where private_url=:privateUrl";
		if(excludeId>0){
			sql+=" and id!=:excludeId";
		}
		Query query = s.createSQLQuery(sql);
		query.setString("privateUrl", privateUrl);
		if(excludeId>0){
			query.setInteger("excludeId", excludeId);
		}
		int count = Integer.parseInt((query.uniqueResult().toString()));

		if (count > 0) {
			return true;
		} else {
			return false;
		}
	}

	public void update(User user) {

		sessionFactory.getCurrentSession().update(user);
	}

	@SuppressWarnings("unchecked")
	public List<Tag> getUserTags(int userId) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "select t.* from tag t where t.id in (select ut.tag_id from user_tag as ut where ut.user_id=:userId)";
		Query query = s.createSQLQuery(hql).addEntity(Tag.class);
		query.setInteger("userId", userId);
		List<Tag> tags = query.list();
		return tags;

	}

	public void reduceArticleNum(int userId) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.articleNum=u.articleNum-1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", userId);
		q.executeUpdate();

	}

	public void reduceFollowNum(int id) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.followNum=u.followNum-1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();

	}

	public void reduceFansNum(int id) {
		Session s = sessionFactory.getCurrentSession();
		String hql = "update User as u set u.fansNum=u.fansNum-1 where u.id=:id";
		Query q = s.createQuery(hql);
		q.setInteger("id", id);
		q.executeUpdate();

	}

	public Page findActiveUserByPage(int page, int pageSize) {
		Session s = sessionFactory.getCurrentSession();
		String sql = "select u.* from user u order by u.last_login_time desc";
		Query query = s.createSQLQuery(sql).setResultTransformer(
				Transformers.ALIAS_TO_ENTITY_MAP);
		query.setMaxResults(pageSize);
		query.setFirstResult((page - 1) * pageSize);
		Page pageobj = new Page();
		pageobj.setList(query.list());
		pageobj.setCurrentPage(page);
		return pageobj;
	}
	
	public Page findHotUserByPage(int page, int pageSize) {
		Session s = sessionFactory.getCurrentSession();
		String sql = "select u.* from user u order by (u.answers_num+u.article_num) desc";
		Query query = s.createSQLQuery(sql).setResultTransformer(
				Transformers.ALIAS_TO_ENTITY_MAP);
		query.setMaxResults(pageSize);
		query.setFirstResult((page - 1) * pageSize);
		Page pageobj = new Page();
		pageobj.setList(query.list());
		pageobj.setCurrentPage(page);
		return pageobj;
	}

}
